package com.explorex.infra.puma.gateway.netty.ws;


import com.explorex.infra.puma.gateway.netty.common.AbstractBaseServer;
import com.explorex.infra.puma.gateway.netty.ws.handler.ChannelManagerHandler;
import com.explorex.infra.puma.gateway.netty.ws.handler.HttpServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelOption;
import io.netty.channel.WriteBufferWaterMark;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketFrameAggregator;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.flush.FlushConsolidationHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import lombok.Getter;
import lombok.Setter;

/**
 * @author: JacceYang
 * @createTime: 2022/07/14 9:19 下午
 * @description: WebSocketEvent handler
 */
public class HttpServer extends AbstractBaseServer {
    @Getter
    @Setter
    private BaseHttpResource httpResource;

    @Override
    protected void initSocketChannel(SocketChannel ch) {
        super.initSocketChannel(ch);
        ch.pipeline().addLast(new HttpServerCodec());
        ch.pipeline().addLast(new HttpObjectAggregator(65536));
        ch.pipeline().addLast(new ChunkedWriteHandler());
        ch.pipeline().addLast(new WebSocketServerCompressionHandler());
        ch.pipeline().addLast(new WebSocketFrameAggregator(1*1024*1024));
        ch.pipeline().addLast(new FlushConsolidationHandler(5));
        HttpServerHandler httpServerHandler = new HttpServerHandler(this, httpResource);
        processHttpHandler(httpServerHandler);
        ch.pipeline().addLast("http", httpServerHandler);
        ch.pipeline().addLast(new ChannelManagerHandler());
    }

    protected void processHttpHandler(HttpServerHandler httpServerHandler) {
    }

    @Override
    protected void initServerBootStrap(ServerBootstrap serverBootstrap) {
        super.initServerBootStrap(serverBootstrap);
        serverBootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(512 * 1024,   1024 * 1024))
                .option(ChannelOption.SO_REUSEADDR, true);
    }
}
